package com.objecteffects.ilmp.web.utils;

import javax.inject.Inject;

import com.objecteffects.ilmp.model.UserEntity;
import com.objecteffects.ilmp.service.UserEntityService;
import com.objecteffects.ilmp.web.action.BaseActionBean;
import com.objecteffects.ilmp.web.action.IlmpActionBeanContext;
import com.objecteffects.ilmp.web.action.UserLoginActionBean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.ExecutionContext;
import net.sourceforge.stripes.controller.Interceptor;
import net.sourceforge.stripes.controller.Intercepts;
import net.sourceforge.stripes.controller.LifecycleStage;

/**
 * @author Rusty Wright
 */
@Intercepts(LifecycleStage.ActionBeanResolution)
public class LoginRequiredInterceptor implements Interceptor {
    private final transient Logger log = LoggerFactory
        .getLogger(LoginRequiredInterceptor.class);

    private final CheckLoginRequired checkLoginRequired;
    private final IlmpCookie IlmpCookie;
    private final UserEntityService userEntityService;

    @Inject
    LoginRequiredInterceptor(final CheckLoginRequired _checkLoginRequired,
        final IlmpCookie _ilmpCookie,
        final UserEntityService _userEntityService) {
        this.checkLoginRequired = _checkLoginRequired;
        this.IlmpCookie = _ilmpCookie;
        this.userEntityService = _userEntityService;
    }

    @Override
    public Resolution intercept(final ExecutionContext context)
        throws Exception {
        final Resolution resolution = context.proceed();

        final IlmpActionBeanContext tabContext =
            (IlmpActionBeanContext) context.getActionBeanContext();

        final BaseActionBean actionBean =
            (BaseActionBean) context.getActionBean();

        final Class<? extends BaseActionBean> clazz = actionBean.getClass();

        if (this.checkLoginRequired.isLoginRequired(clazz)) {
            if (this.findUserFromCookies(tabContext)) {
                return resolution;
            }

            final Long contextUserEntityId = tabContext.getUserId();

            if (contextUserEntityId == null) {
                this.log.debug("redirecting to login page");

                return new RedirectResolution(UserLoginActionBean.class);
            }
        }

        return resolution;
    }

    /**
     * @return true if their browser has our cookie. Sets the userId
     *         in the context if the cookie was found.
     *
     * @param resolution
     * @param tabContext
     */
    private boolean findUserFromCookies(
        final IlmpActionBeanContext tabContext) {
        final String hash =
            this.IlmpCookie.findHashFromCookies(tabContext.getRequest());

        if (hash == null) {
            return false;
        }

        final UserEntity userEntity = this.userEntityService.findByHash(hash);

        if (userEntity == null) {
            return false;
        }

        this.log.debug("cookie user: {}", userEntity);

        tabContext.setUserId(userEntity.getId());

        return true;
    }
}
